iT邦幫忙

2024 iThome 鐵人賽

DAY 28
0
Modern Web

Dive into CSS Challenge:從問題到解決方案的實踐之旅系列 第 28

Day 28 - CSS Challenge #15:Upload File via Antd (上)

  • 分享至 

  • xImage
  •  

題目

CSS Challenge Day15

  • 上傳檔案及各種狀況的判斷介面
    https://ithelp.ithome.com.tw/upload/images/20241012/20169403Cnd6h6e5PH.png

上面的圖是題目,而我們要做出幾乎一樣的樣子,題目中還有附上出題官方的CodePen,也有附上給我們解題用的template,當我們真的不會的時候,還是可以參考他們的寫法,所以沒有想像中困難。

我做好的此題CSS Challeage解答

題目分析

  • 可以 drag 上傳
  • 可以 click button 上傳
  • 上傳後會顯示成功或失敗
  • 上傳後會顯示檔案名稱
    因為這些功能 Antd 都有,加上工作上常使用,比較熟悉,所以我的目標就決定使用 typesrcipt 跟 antd 來做出跟題目類似的樣子。

但是使用 Antd 比較麻煩的地方就是上傳後預覽的樣子,要讓 button 上傳後觸發 dragger 的預覽跟進度條,是跟 CSS Challenge 比較無關的地方,所以這部分我不會著重去寫,而會在後面大概講解一下怎麼修改 antd 的樣式。

Antd

必須承認我是懶人,在看到這題的時候覺得「這是哪門子的 CSS Challenge?這根本是 Javascript Challenge 吧」,看到官方的示範中,Javascript 寫的快要跟 CSS 一樣多,其實我有點不開燻。

個人覺得喜歡 CSS 的人不是每個人都喜歡 JS,這兩個東西雖然相輔相成但不是必須,有很多喜歡寫 CSS 的人是致力於使用純 CSS 做到各種動畫、選單等等,所以說好的 CSS 挑戰卻來一個要寫這麼多 JS 的,我不開心!

但既然題目愛寫 JS,我就來給他寫到底,這次就用我工作上會用到的 Typescript 搭配 Antd 來寫個夠!而且這種寫法,我自己覺得還比較可以真的玩到 CSS。

那我們就開始吧。

Javascript Preprocessor

https://ithelp.ithome.com.tw/upload/images/20241012/20169403wyuO7ueuVi.png
首先在這邊我選擇 Typescript。
接著底下的 External Scripts/Pens 有興趣的人可以點去我的這支CodePen看,想跟著做的也可以去裡面複製我設定好的 Scripts。

HTML

<div id="container"></div>

<script>const mountNode = document.getElementById('container');</script>

一樣使用 CSS Challenge 官方提供的 template 來開場,然後我們就把 html 內容全部改掉。

因為我等等所有的東西都要在 typescript 裡面寫完,所以這邊就單純的放一個 div,設定好 id 並且 mountNode 到這個指定的 id 裡面( id 名稱你可以改成你自己喜歡的),那準備工作就作好了。

JS

const { createRoot } = ReactDOM;

const { CloudUploadOutlined, UploadOutlined } = icons;
const { message, Upload, Button } = antd;
const { Dragger } = Upload;

先把會使用到的東西 import 進來

const DragUploader = ... 
const ClickUploader = ...
  • DragUploader:這是拖曳檔案的組件名稱,是個拖曳檔案的區塊,直接點擊這個區塊也可以上傳檔案,裡面主要使用 antdDragger
    https://ithelp.ithome.com.tw/upload/images/20241012/20169403hLMU0cFPGB.png

  • ClickUploader:這是上傳檔案的組件名稱,樣式看起來就是一顆按鈕,裡面主要使用 antdUpload
    https://ithelp.ithome.com.tw/upload/images/20241012/20169403OsXTrus6j0.png

我這邊的目標就是,使用 antd 的 DraggerUpload 兩個組件。
只要這兩個組件其中任何一個有檔案觸發要上傳,都會觸發 Dragger 的上傳邏輯,顯示他的上傳預覽畫面。

也就是這兩個東西是連動的,然後主要畫面會是以 Dragger 為主。

Dragger

我在 DragUploader 內使用 useState 來管理 fileList 也就是上傳的檔案的文件列表。
使用 React.useImperativeHandle 來觸發 dragPropsonChange,讓它開始上傳,並顯示上傳進度的畫面。

Upload

我在 ClickUploader 加上了 showUploadList={false}onChange 事件,讓它去觸發 DragUploader 的上傳邏輯,並且自己這邊不做任何上傳。

整個畫面架構

const App = () => {
  const dragRef = React.useRef();

  return (
    <div className="frame">
      <div className="center">
        <div className="title">Drop file to upload</div>
        <div className="content">
          <div className="dragWrapper">
            <DragUploader ref={dragRef} />
          </div>
          <div className="btnWrapper">
            <ClickUploader dragRef={dragRef} />
          </div>
        </div>
      </div>
    </div>
  );
};
createRoot(mountNode).render(<App />);

因為主題主要還是 CSS Challenge,所以這塊我就不多說,我們直接看 return 內的 HTML 結構就可以。

  • .frame:還是保留 template 內給我們的樣式。
  • .center:這邊我等等會做成外面的白色卡片。
  • .title:卡片的title。
  • .content:這邊就會放兩個上傳的 uploader 及預覽檔案名稱的部分。
    • .dragWrapper .btnWrapper:因為要去修改 antd 的 className,所以在這邊我還是把上下兩個上傳的區塊拆開來,這樣等等修改 CSS 的時候會比較輕鬆一點。

那這樣就差不多前置完成,剛做完會長這樣
https://ithelp.ithome.com.tw/upload/images/20241012/20169403ZyMTQraGMT.png

我們明天再來修改裡面的 CSS


Wrap up and go home

希望改變了這種按照步驟的寫法,能讓更多人看得懂,也能跟我一樣喜歡上寫CSS。

那今天就先到這裡,明天我們再繼續來玩下一集。


上一篇
Day 27 - CSS Challenge #14:Flip Card(下)
下一篇
Day 29 - CSS Challenge #15:Upload File via Antd (下)
系列文
Dive into CSS Challenge:從問題到解決方案的實踐之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言